const CryptoJS = require("crypto-js");

class AES {
	constructor(key) {
		this.key = key;
		this.method = "aes-128-cbc";
	}





	generateRandomIv(length) {
		const iv = new Uint8Array(length);
		wx.getSystemInfo({
			success: function(res) {
				for (let i = 0; i < iv.length; i++) {
					iv[i] = Math.floor(Math.random() * 256);
				}
			}
		});
		return CryptoJS.lib.WordArray.create(iv);
	}


	encrypt(plaintext) {
		const iv = this.generateRandomIv(16);
		const ciphertext = CryptoJS.AES.encrypt(
			plaintext,
			this.key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }
		);
		return iv.concat(ciphertext.ciphertext).toString(CryptoJS.enc.Base64);
	}




	decrypt(ciphertext) {
		ciphertext = CryptoJS.enc.Base64.parse(ciphertext);
		const iv = ciphertext.clone();
		iv.sigBytes = 16;
		iv.clamp();
		ciphertext.words.splice(0, 4);
		ciphertext.sigBytes -= 16;
		const decrypted = CryptoJS.AES.decrypt({ ciphertext: ciphertext },
			this.key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }
		);
		const plaintext = decrypted.toString(CryptoJS.enc.Utf8);
		return plaintext;
	}

	toHex() {
		return this.key.toString(CryptoJS.enc.Hex);
	}

	static fromHex(hexString) {
		return new AES(CryptoJS.enc.Hex.parse(hexString));
	}

	static fromBase64(base64String) {
		return new AES(CryptoJS.enc.Base64.parse(base64String));
	}

	toBase64() {
		return this.key.toString(CryptoJS.enc.Base64);
	}
}

// 导出 AES 类
module.exports = AES;